/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.zhuangfei.hos_timetableview.view;

import com.zhuangfei.timetable.utils.EventUtil;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;
import ohos.system.version.SystemVersion;

/**
 * 弹性滚动布局，下拉时会反弹
 */
public class ElasticScrollView extends DirectionalLayout {
    private Component inner;
    private float downY;
    private float deltaY;
    private Rect normal = new Rect();
    private boolean animationFinish = true;

    public ElasticScrollView(Context context) {
        this(context, null);
    }

    public ElasticScrollView(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public ElasticScrollView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        // sdk7以上事件和手势不分离，需要使用setForwardTouchListener来监听触摸手势
        if (SystemVersion.getApiVersion() >= 7) {
            setForwardTouchListener(new ForwardTouchListener() {
                @Override
                public boolean onForwardTouch(Component component, TouchEvent touchEvent) {
                    return onTouch(component, touchEvent);
                }
            });
        } else {
            setTouchEventListener(new TouchEventListener() {
                @Override
                public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                    return onTouch(component, touchEvent);
                }
            });
        }
    }

    public boolean onTouch(Component component, TouchEvent event) {
        if (getChildCount() > 0) {
            inner = getComponentAt(0);
        }
        if (inner == null) {
            return false;
        } else {
            return commOnTouchEvent(event);
        }
    }

    private boolean commOnTouchEvent(TouchEvent event) {
        if (animationFinish) {
            switch (event.getAction()) {
                case TouchEvent.PRIMARY_POINT_DOWN:
                    downY = EventUtil.getRawY(event);
                    break;
                case TouchEvent.PRIMARY_POINT_UP:
                    downY = 0;
                    if (isNeedAnimation()) {
                        animation();
                    }
                    break;
                case TouchEvent.POINT_MOVE:
                    final float preY = (downY == 0 ? EventUtil.getRawY(event) : downY);
                    float nowY = EventUtil.getRawY(event);
                    deltaY = (nowY - preY) / 2;
                    // 当滚动到最上或者最下时就不会再滚动，这时移动布局
                    if (isNeedMove()) {
                        if (normal.isEmpty()) {
                            // 保存正常的布局位置
                            normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());
                        }
                        // 移动布局
                        inner.setTranslationY(deltaY);
                    }
                    break;
                default:
                    break;
            }
        }
        return true;
    }

    // 开启动画移动
    private void animation() {
        // 开启移动动画
        AnimatorValue mProgerssRotateAnim = new AnimatorValue();
        mProgerssRotateAnim.setDuration(200);
        mProgerssRotateAnim.setCurveType(Animator.CurveType.LINEAR);
        mProgerssRotateAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                inner.setTranslationY(deltaY - deltaY * value);
            }
        });
        mProgerssRotateAnim.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {

            }

            @Override
            public void onEnd(Animator animator) {
                inner.setTranslationY(0);
                normal.clear();
                animationFinish = true;
            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        });
        mProgerssRotateAnim.start();
    }

    // 是否需要开启动画  
    private boolean isNeedAnimation() {
        return !normal.isEmpty();
    }

    // 是否需要移动布局  
    private boolean isNeedMove() {
        return true;
    }

}  